import traceback

from flask import Blueprint, request, g, make_response
from flask_restful import Resource, Api, reqparse, marshal, fields, current_app
from sqlalchemy import or_, and_, not_
from marshmallow import Schema, fields
from marshmallow_sqlalchemy import SQLAlchemySchema, SQLAlchemyAutoSchema, auto_field

from common.es.es import ES
from common.models import rds, db, cache
from common.models.book import Book
from common.utils.custom_output_json import custom_output_json
from common.model_fields.book_fields import book_fields


book_bp = Blueprint('book_bp', __name__)
api = Api(book_bp)


@api.representation('application/json')
def output_json(data, code=200, headers=None):
    return custom_output_json(data, code, headers)


class BookSchema(SQLAlchemyAutoSchema):
    # title = fields.String()

    class Meta:
        model = Book
        # fields = ['__all__']
        ordered = True  # 转换成有序字典


class BookResource(Resource):
    """
    图书管理API
    get 获取图书
    post 添加图书
    put 修改图书信息
    delete 删除图书信息
    """

    def get(self):
        """
        获取所有的 未删除的书籍列表
        :return:
        """

        book_list = list(Book.query.filter_by(is_delete=0).order_by(Book.pub_date.desc()).all())
        data1 = BookSchema(many=True).dumps(book_list)
        return data1

    def post(self):
        """
        添加书籍
        :return:
        """
        parser = reqparse.RequestParser()
        parser.add_argument('title')
        parser.add_argument('read', 0)
        args = parser.parse_args()
        title = args.get('title')
        read = args.get('read')
        book = Book(title=title, read=read)
        db.session.add(book)
        db.session.commit()
        return marshal(book, book_fields)

    def put(self):
        """
        修改书籍名称
        :return:
        """
        parser = reqparse.RequestParser()
        parser.add_argument('title')
        parser.add_argument('id')
        args = parser.parse_args()
        title = args.get('title')
        id = args.get('id')
        book = Book.query.get(id)
        if not book:
            return {'message': 'book is not exist!', 'code': 405}
        book.title = title
        db.session.commit()
        return marshal(book, book_fields)

    def delete(self):
        parser = reqparse.RequestParser()
        parser.add_argument('id')
        args = parser.parse_args()
        id = args.get('id')
        book = Book.query.get(id)
        if not book:
            return {'message': 'book is not exist!', 'code': 405}
        book.is_delete = 1
        db.session.commit()
        return marshal(book, book_fields)


class BookSearch(Resource):
    """
    搜索标签
    """

    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument('search', required=True)
        args = parser.parse_args()
        search = args.get('search')
        # book = Book.query.whoosh_search(search, like=True).all()
        # return marshal(book, book_fields)

        es = ES(index_name='book')
        result = es._search(search, fields=['pub_date', 'title'])
        return result


api.add_resource(BookResource, '/book_resource', endpoint='book_resource')
api.add_resource(BookSearch, '/book_search', endpoint='book_search')
